package com.game.doudizhu.service;

import com.game.doudizhu.model.Card;
import com.game.doudizhu.model.GameState;
import com.game.doudizhu.repository.CardRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class CardService {

    @Autowired
    private CardRepository cardRepository;

    @Transactional
    public List<Card> initializeAndDealCards(Long roomId) {
        // 创建一副新牌
        List<Card> cards = createNewDeck();
        
        // 洗牌
        shuffleCards(cards);
        
        // 保存牌到数据库
        cards.forEach(card -> card.setRoomId(roomId));
        return cardRepository.saveAll(cards);
    }

    public void distributeCards(List<Card> cards, GameState gameState) {
        // 确保牌已经被打乱
        shuffleCards(cards);
        
        int playerCount = gameState.getRoom().getPlayers().size();
        if (playerCount != 3) {
            throw new IllegalStateException("玩家数量必须为3人");
        }

        // 分配玩家手牌
        Map<Long, List<Card>> playerCards = new HashMap<>();
        List<Long> playerIds = new ArrayList<>(gameState.getRoom().getPlayers().stream()
                .map(p -> p.getId())
                .collect(java.util.stream.Collectors.toList()));

        // 为每个玩家创建手牌列表
        playerIds.forEach(id -> playerCards.put(id, new ArrayList<>()));

        // 发牌（每人17张）
        for (int i = 0; i < 51; i++) {
            int playerIndex = i % 3;
            playerCards.get(playerIds.get(playerIndex)).add(cards.get(i));
        }

        // 剩余3张作为地主牌
        List<Card> landlordCards = new ArrayList<>();
        for (int i = 51; i < 54; i++) {
            landlordCards.add(cards.get(i));
        }

        // 更新游戏状态
        gameState.setPlayerCards(playerCards);
        gameState.setLandlordCards(landlordCards);
    }

    private List<Card> createNewDeck() {
        List<Card> cards = new ArrayList<>();
        long id = 1;

        // 添加普通牌
        Card.Suit[] suits = {Card.Suit.HEARTS, Card.Suit.DIAMONDS, Card.Suit.CLUBS, Card.Suit.SPADES};
        String[] ranks = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

        for (Card.Suit suit : suits) {
            for (String rank : ranks) {
                Card card = new Card();
                card.setId(id++);
                card.setSuit(suit);
                card.setRank(rank);
                card.setWeight(getWeight(rank));
                cards.add(card);
            }
        }

        // 添加大小王
        Card smallJoker = new Card();
        smallJoker.setId(id++);
        smallJoker.setSuit(Card.Suit.JOKER);
        smallJoker.setRank("SMALL");
        smallJoker.setWeight(16);
        cards.add(smallJoker);

        Card bigJoker = new Card();
        bigJoker.setId(id);
        bigJoker.setSuit(Card.Suit.JOKER);
        bigJoker.setRank("BIG");
        bigJoker.setWeight(17);
        cards.add(bigJoker);

        return cards;
    }

    private void shuffleCards(List<Card> cards) {
        // 使用当前时间作为随机种子
        long seed = System.currentTimeMillis();
        Random random = new Random(seed);
        
        // Fisher-Yates 洗牌算法
        for (int i = cards.size() - 1; i > 0; i--) {
            int j = random.nextInt(i + 1);
            Card temp = cards.get(i);
            cards.set(i, cards.get(j));
            cards.set(j, temp);
        }
    }

    private int getWeight(String rank) {
        switch (rank) {
            case "3": return 3;
            case "4": return 4;
            case "5": return 5;
            case "6": return 6;
            case "7": return 7;
            case "8": return 8;
            case "9": return 9;
            case "10": return 10;
            case "J": return 11;
            case "Q": return 12;
            case "K": return 13;
            case "A": return 14;
            case "2": return 15;
            default: return 0;
        }
    }

    @Transactional
    public void clearRoomCards(Long roomId) {
        cardRepository.removeCardsByRoomId(roomId);
    }

    /**
     * 根据牌面获取权重值
     * 3-10 对应权重 3-10
     * J、Q、K、A、2 对应权重 11-15
     * 小王、大王对应权重 16、17
     */
    public static int getWeightByRank(String rank) {
        if (rank == null) {
            return 0;
        }
        
        switch (rank.toUpperCase()) {
            case "3": return 3;
            case "4": return 4;
            case "5": return 5;
            case "6": return 6;
            case "7": return 7;
            case "8": return 8;
            case "9": return 9;
            case "10": return 10;
            case "J": return 11;
            case "Q": return 12;
            case "K": return 13;
            case "A": return 14;
            case "2": return 15;
            case "SMALL": return 16;  // 小王
            case "BIG": return 17;    // 大王
            default: return 0;
        }
    }

    /**
     * 根据权重值获取牌面
     */
    public static String getRankByWeight(int weight) {
        switch (weight) {
            case 3: return "3";
            case 4: return "4";
            case 5: return "5";
            case 6: return "6";
            case 7: return "7";
            case 8: return "8";
            case 9: return "9";
            case 10: return "10";
            case 11: return "J";
            case 12: return "Q";
            case 13: return "K";
            case 14: return "A";
            case 15: return "2";
            case 16: return "SMALL";  // 小王
            case 17: return "BIG";    // 大王
            default: return "";
        }
    }

    /**
     * 比较两张牌的大小
     * @return 正数表示 card1 大，负数表示 card2 大，0 表示相等
     */
    public static int compareCards(Card card1, Card card2) {
        if (card1 == null || card2 == null) {
            throw new IllegalArgumentException("Cards cannot be null");
        }
        
        // 先比较权重
        int weightCompare = Integer.compare(getWeightByRank(card1.getRank()), 
                                         getWeightByRank(card2.getRank()));
        if (weightCompare != 0) {
            return weightCompare;
        }
        
        // 权重相同时比较花色
        return card1.getSuit().compareTo(card2.getSuit());
    }

    /**
     * 检查是否是有效的牌面值
     */
    public static boolean isValidRank(String rank) {
        if (rank == null) {
            return false;
        }
        
        String upperRank = rank.toUpperCase();
        return upperRank.matches("[3-9]|10|[JQKA2]|SMALL|BIG");
    }
} 